perm filename SAMPLE.DOC[TEX,DEK] blob
sn#427769 filedate 1979-03-28 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 {{\head{Introduction} \titlepage \runninglefthead{EXAMPLE OF TEXDOC}\setcount0 1
C00007 00003 {{ Here are samples of integer definitions that will cause {\:c UNDOC} to make
C00011 00004 {{\head{Data structures}
C00014 00005 {{\head{Input}
C00018 00006 { Input from external file,
C00021 00007 { Scan a control ... } =
C00024 00008 { Move to next line of file, or
C00032 00009 { Input from token list, \goto\ \\{do_get_next} if end of list
C00039 ENDMK
C⊗;
{{\head{Introduction} \titlepage \runninglefthead{EXAMPLE OF TEXDOC}\setcount0 1
This is a sample ``style sheet'' to illustrate the recommended conventions
desirable for \TEX\ documentation. Explanatory material that has been enclosed
in $\{\{$ and $\}\}$ (like the explanatory material you are now reading)
should be acceptable \TEX\ input; it will be removed from the corresponding
{\:c PASCAL} program produced by {\:c UNDOC}, but it will be typeset in place as
part of the printed documentation produced by {\:c TEXDOC}.
Documentation files like this one have the suffix \.{.DOC}; the {\:c UNDOC} program
converts them into files with suffix \.{.PAS}, and the {\:c TEXDOC} program converts
them into files with suffix \.{.TEX}.
The program segment below is the \\{get_next} procedure, recoded from page 10 of
the original {\:c SAIL} version in file \.{TEXSYN.SAI}. The program conventions have
changed slightly, mainly because \\{inbuf} and \\{curbuf} now are simply
pointers to an ascii array \\{instack}, not variables of type {\bf string}.
Some of the names have changed too; for example, \\{align_insert} has been
substituted for the less appropriate name \\{aligndelim}. The variable
\\{page_warning} is now of type (\\{OK}, \\{def_of}, \\{use_of}). And so on.}}
{{ Here are samples of integer definitions that will cause {\:c UNDOC} to make
corresponding substitutions in the program text:}}
{ escape } := 0 {{ escape delimiter (\.{\\} in \TEX\ manual) }}
{ lbrace } := 1 {{ begin block symbol ( \.{\char'173} ) }}
{ rbrace } := 2 {{ end block symbol ( \.{\char'176} ) }}
{ mathbr } := 3 {{ math break ( \.{\char'44} ) }}
{ tabmrk } := 4 {{ tab mark ( \.{\char'26} ) }}
{ carret } := 5 {{ carriage return or comment ( \.{\char'45} ), \.{\\cr} }}
{ macprm } := 6 {{ macro parameter ( \.{\char'43} ) }}
{ supmrk } := 7 {{ superscript ( \.{\char'136} ) }}
{ submrk } := 8 {{ subscript ( \.{\char'175} ) }}
{ ignore } := 9 {{ characters to ignore }}
{ spacer } := 10 {{ characters treated as blank space }}
{ letter } := 11 {{ characters treated as letters }}
{ otherchar } := 12 {{ none of the above character types }}
{ parend } := 13 {{ end of paragraph }}
{ match } := 14 {{ macro parameter matching }}
{ charcodes } := 13 {{ number of distinct character types }}
{ tokenlist } := 0 {{ scanning a token list }}
{ midline } := 1 {{ scanning a line of characters }}
{ skipblanks } := midline+charcodes {{ like \\{midline} but ignoring blanks }}
{ newline } := skipblanks+charcodes {{ beginning a new line of characters }}
{ line_feed } := '12 {{ end of line in ascii input file }}
{ form_feed } := '14 {{ end of page in ascii input file }}
{ carriage_return } := '15 {{ precedes end of line in ascii input file }}
{ hashsize } := 353 {{ hashtable size, must be prime and less than
$\\{charsize}-127$ }}
{ texpars } := 10 {{ number of distinct parameters settable by \.{\\chpar} }}
{ eqtbsize } := hashsize+128+128+texpars {{ size of table for current values }}
{ chartype_offset } := hashsize+128 {{ location of character type in \\{eqtb} }}
{ tracing_offset } := hashsize+268 {{ location of tracing control in \\{eqtb} }}
{ param } := 0 {{ \\{recovery} code for parameters }}
{ ujlist } := 1 {{ \\{recovery} code for $u↓j$ lists in alignments }}
{ vjlist } := 2 {{ \\{recovery} code for $v↓j$ lists in alignments }}
{ inserted } := 3 {{ \\{recovery} code for an inserted token list }}
{ do_get_next } := 1 {{ label in \\{get_next} procedure }}
{ end_get_next } := 2 {{ label in \\{get_next} procedure }}
{ inner_switch } := 3 {{ label in \\{get_next} procedure }}
{{\head{Data structures}
It isn't clear exactly what types should be declared, but the tentative
types listed below appear in this example. The roles of \\{loc} and \\{recovery}
have been reversed for character files, so that \\{loc} is always of type
\\{integer} and \\{recovery} is always of type \\{inflnk}. The \\{info} field
of \\{recovery} is now set to positive values in all cases, instead of using
conventions like $-l$, etc.}}
type inflnk = packed record info: 0..131071; link: 0..32767 end;
token = packed record cmd: 0..15; chr: 0..1023 end;
toklnk = packed record tok: token; link: 0..32767 end;
eqtbval = packed record idcmd: 0..127; idlev: 0..31; idlen: 0..7;
link: 0..32767 end;
tracebits = packed record mmm:0..511; nnn: 0..511; ddtflag: 0..1; inputflag: 0..1;
replflag: 0..1; dumpflag: 0..1; detailflag: 0..1; overflag: 0..1 end;
ee = record case 1..4 of
1: (eq: eqtbval);
2: (int: integer);
3: (pts: real);
4: (tr: tracebits)
end;
mm = record case 1..5 of
1: (pts: real);
2: (int: integer);
3: (il: inflnk);
4: (tl: toklnk);
5: (something_else_probably_too)
end;
var mem = array 0..memsize-1 of mm;
eqtb = array 0..eqtbsize-1 of ee;
{{Here's an example of a macro with a parameter:}}
{ chartype } #= eqtb[#+chartype_offset].int
{{\head{Input}
The \\{get_next} procedure acts as \TEX's eyes and mouth, as they read and
gobble up source files or stored tokens. The main duty of \\{get_next} is to
input one token, setting \\{curcmd} to the code for the corresponding command
and setting \\{curchar} to the code for the corresponding character. Furthermore,
the value of \\{hashentry} is made nonnegative if and only if the new input token
is a control sequence (and, if so, \\{hashentry} is set to the corresponding
location in \\{eqtb}). Although this procedure has to handle a lot of different
cases, an attempt has been made to keep its inner loop reasonably short and fast.}}
procedure get_next; {{ sends next input token to \\{curcmd} and \\{curchar} }}
label do_get_next, {{ go here to get the next token }}
end_get_next, {{ go here when the next token has been got }}
inner_switch; {{ go here to read the next character }}
var { Locals for \\{get_next} }
begin
do_get_next:
if state <> tokenlist then {{ Reading from an external file }}
{ Input from external file,
\goto\ \\{end_get_next} with paragraph end token if end of file,
\goto\ \\{do_get_next} if no input token found }
else { Input from token list, \goto\ \\{do_get_next} if end of list
or if a parameter needs to be expanded };
if { End of alignment entry sensed? } then
{ Insert the $\langle v↓j \rangle$ list and \goto\ \\{do_get_next} };
end_get_next:
end
{ End of align ... } = alignstate = 0 and ((curcmd=tabmrk) or (curcmd=carret))
{ Insert the $\lan ... } =
begin align_insert;
hashentry := -1; {{ this resets \\{hashentry} in case it points to \.{\\cr} }}
goto do_get_next
end
{ Input from external file,
\goto\ \\{end_get_next} with paragraph end token if end of file,
\goto\ \\{do_get_next} if no input token found } =
if curbuf < instack_ptr then {{ Current line not empty }}
begin { Read one character of the input };
{ Change state if necessary, and \goto\ \\{inner_switch} if the
current character should be ignored }
end
else begin { Move to next line of file, or
\goto\ \\{end_get_next} with paragraph end token if end of file,
or \goto\ \\{do_get_next} if inserted list just ended };
goto inner_switch
end
{ Read one char ... } =
begin curchar := ord(instack[instack_ptr]);
instack_ptr := instack_ptr + 1;
curcmd := chartype(curchar)
end
{ Change state ... } =
case state + curcmd of
{ Cases where character is ignored }: goto inner_switch;
{ Cases involving an escape character }: { Scan a control sequence };
{ Handle situations involving spaces, braces, changes of state};
others: { Do nothing }
end
{ Cases where character is ignored } = midline+ignore, skipblanks+ignore,
skipblanks+spacer, newline+ignore, newline+spacer
{ Cases involving an escape character } = midline+escape, skipblanks+escape,
newline+escape
{ Do nothing } =
{ Scan a control ... } =
begin control_seq;
with eqtb[hashentry].eq do
begin curcmd := idcmd; curchar := link
end;
state := skipblanks
end
{ Handle situations inv... } =
midline+spacer: { Set \\{skipblanks} state and emit a space };
midline+carret: { Set \\{newline} state and emit a space };
skipblanks+carret: { Set \\{newline} state and \goto\ \\{inner_switch} };
midline+lbrace: alignstate := alignstate + 1;
skipblanks+lbrace, newline+lbrace: { Set \\{midline} state and
increase \\{alignstate} };
midline+rbrace: alignstate := alignstate -1;
skipblanks+rbrace, newline+rbrace: { Set \\{midline} state and
decrease \\{alignstate} };
{ Situations leading to \\{midline} state }: state := midline
{ Set \\{skipblanks} state ... } =
begin state := skipblanks;
curchar := ord(' ')
end
{ Set \\{newline} state and emit ... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
curcmd := spacer;
curchar := ord(' ')
end
{ Set \\{newline} state and \go... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
goto inner_switch
end
{ Situations leading to \\{midline} ... } = skipblanks+mathbr, skipblanks+tabmrk,
skipblanks+macprm, skipblanks+supmrk, skipblanks+submrk, skipblanks+letter,
skipblanks+otherchar, newline+mathbr, newline+tabmrk, newline+macprm,
newline+letter, newline+otherchar
{ Set \\{midline} state and in... } =
begin state := midline;
alignstate := alignstate + 1
end
{ Set \\{midline} state and de... } =
begin state := midline;
alignstate := alignstate - 1
end
{ Move to next line of file, or
\goto\ \\{end_get_next} with paragraph end token if end of file,
or \goto\ \\{do_get_next} if inserted list just ended } =
begin if filename <> 0 then {{ Reading from a character file }}
{ Read next line into input buffer }
else if inptr <> 0 then {{ Input was text inserted by user during error recovery }}
begin popinput; {{ Restore previous input source }}
goto do_get_next
end
else { Input online from terminal into input buffer };
curbuf := inbuf {{ Prepare to scan input buffer }}
end
{ Read next line ... } =
begin inputln; {{ Read current file up to line feed or form feed or eof }}
if eoff then { Process end of file and \goto\ \\{end_get_next} with \\{parend} };
{ Trace the input line if requested };
{ Advance line and page number }
end
{ Process end of file and ... } =
begin write(')'); {{ Show user that the file has been read }}
release(loc); {{ Close the file }}
{ Check if end of page is {\:c OK} };
popinput; {{ Restore previous status }}
curcmd := parend; curchar := 0;
goto end_get_next
end
{ Check if end of page is... } =
if page_warning <> OK then page_end_error
{ Trace the input line if requested } =
if eqtb[trace_offset].tr.inputflag then
begin println;
for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf]);
{ Input online ... };
end
{ Input online ... } =
begin println; print('*'); {{ prompt the user }}
inputln;
{ Echo the input on the output file };
{ Define the escape character if the first character has just been read };
end
{ Echo ... } = for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf])
{ Define the escape ... } =
if (escapechar<0) and (ord(instack[inbuf])<>carriage_return) then
begin escapechar := ord(instack[inbuf]);
chartype(escapechar) := escape;
end
{ Advance line and page number } =
with recovery do
if brchar = form_feed then {{ End of page }}
begin info := info + 1; {{ advance page number }}
print(' '); print(info); {{ print progress report for user }}
link := 0; {{ set line number zero }}
{ Check if end of page is ... }
end
else link := link + 1 {{ advance line number }}
{ Input from token list, \goto\ \\{do_get_next} if end of list
or if a parameter needs to be expanded } =
if loc <> 0 then {{ Current token list is not empty }}
begin { Read next token from token list};
case curcmd of
0 :{ Process a control sequence token };
outpar : { Insert a macro parameter and \goto\ \\{do_get_next} };
lbrace : alignstate := alignstate + 1;
rbrace : alignstate := alignstate - 1;
others: { Do nothing }
end
end
else begin { Process end of token list };
popinput; {{ Return to previous level of input }}
goto do_get_next
end
{ Locals for \\{get_next} } +=
t: token; {{ packed token stored in a token list }}
tt: toklnk; {{ packed token and link stored in a token list }}
{ Read next token ... } =
begin tt := mem[loc].tl;
with tt do
begin t := tok; {{ get token to emit }}
loc := link; {{ advance to next element of token list }}
curchar := t.chr;
curcmd := t.cmd;
end
end
{ Process a control ... } =
begin hashentry := curchar;
with eqtb[curchar].eq do
begin curcmd := idcmd; curchar := link
end
end
{ Insert a macro par... } =
begin pushinput; {{ Begin a new level of input }}
with recovery do
begin loc := parstack[link + curchar]; {{ Beginning of the parameter }}
info := param;
link := loc; {{ \\{recovery} convention for parameter token list }}
goto do_get_next {{ The state remains equal to \\{tokenlist} }}
end
end
{ Process end of token list } =
case recovery.info of
param, vjlist: { Do nothing };
ujlist: alignstate := 0; {{ $u↓j$ list of an alignment has just ended }}
inserted: dslist(recovery); {{ Destroy a temporarily inserted list }}
others: { Process end of macro body }
end
{ Process end of macro body } =
with recovery do
begin delrclink(info); {{ Dereference the macro body }}
while parptr>link do
begin parptr := parptr-1;
dslist(parstack[parptr]) {{ Destroy each parameter }}
end
end